---
title: 'Storyshots migration guide'
---

<Callout variant="info" style={{ marginBottom: "2rem" }}>
  We're actively integrating community feedback to improve the tooling and documentation for snapshot testing with Storybook. If you're interested in participating in this process and helping us improve it. Please fill out this [form](https://forms.gle/jzcMr6cqmZZpH9Z5A) to share your feedback.
</Callout>

<IfRenderer renderer={['react', 'vue' ]}>
  This guide will teach you how to migrate your snapshot tests from the Storyshots addon to Storybook's test-runner or portable stories. Also, you will be able to understand the differences between them and set up, configure, and run snapshot tests using the available tooling provided by Storybook.
</IfRenderer>

<IfRenderer renderer={['angular', 'web-components', 'ember', 'html', 'svelte', 'preact', 'qwik', 'solid' ]}>
  This guide will teach you how to migrate your snapshot tests from the Storyshots addon to Storybook's test-runner. With it, you'll be able to set up, configure your project, and run snapshot tests using the available tooling provided by Storybook.
</IfRenderer>

## Migrating tests from Storyshots

### Prerequisites

Before you begin the migration process, ensure that you have:

* A fully functional Storybook configured with one of the [supported frameworks](../../configure/integration/frameworks.mdx) running the latest stable version (i.e., 7.6 or higher).
* Familiarity with your current Storybook and its testing setup.

### With the test-runner

Storybook test-runner turns all of your stories into executable tests. Powered by [Jest](https://jestjs.io/) and [Playwright](https://playwright.dev/). It's a standalone, framework-agnostic utility that runs parallel to your Storybook. It enables you to run multiple testing patterns in a multi-browser environment, including interaction testing with the [play function](../interaction-testing.mdx), DOM snapshot, and [accessibility testing](../accessibility-testing.mdx).

#### Setup

To get started with the migration process from the Storyshots addon to the test-runner, we recommend that you remove the Storyshots addon and similar packages (i.e., `storybook/addon-storyshots-puppeteer` ) from your project, including any related configuration files. Then, follow the test-runner's [setup instructions](../test-runner.mdx#setup) to install, configure and run it.

#### Extend your test coverage

The Storyshots addon offered a highly customizable testing solution, allowing users to extend testing coverage in various ways. However, the test-runner provides a similar experience but with a different API. Below, you will find additional examples of using the test-runner to achieve results similar to those you achieved with Storyshots.

#### Enable DOM snapshot testing with the test-runner

To enable DOM snapshot testing with the test-runner, you can extend the test-runner's configuration file and use the available [hooks](../test-runner.mdx#test-hook-api) and combine them with Playwright's built-in [`APIs`](https://playwright.dev/docs/test-snapshots) to generate DOM snapshots for each story in your project. For example:

{/* prettier-ignore-start */}

<CodeSnippets path="test-runner-dom-snapshot-testing.md" />

{/* prettier-ignore-end */}

<Callout variant="info" icon="💡">
  If you've set up DOM snapshot tests in your project with the test-runner and enabled the [`index.json` mode](../test-runner.mdx#indexjson-mode) via CLI flag, tests are generated in a temporary folder outside your project, and snapshots get stored alongside them. You'll need to extend the test-runner's configuration and provide a custom snapshot resolver to allow a different location for the snapshots. See the [Troubleshooting](#the-test-runner-does-not-generate-snapshot-files-in-the-expected-directory) section for more information.
</Callout>

#### Run image snapshot tests with the test-runner

By default, the test-runner provides you with the option to run multiple testing patterns (e.g., DOM snapshot testing, [accessibility](../accessibility-testing.mdx#a11y-config-with-the-test-runner)) with minimal configuration. However, if you want, you can extend it to run visual regression testing alongside your other tests. For example:

{/* prettier-ignore-start */}

<CodeSnippets path="test-runner-image-snapshot-testing.md" />

{/* prettier-ignore-end */}

<IfRenderer renderer={['react', 'vue' ]}>
  ### With Portable Stories

  Storybook provides a `composeStories` utility that helps convert stories from a story file into renderable elements that can be reused in your Node tests with JSDOM. It also allows you to apply other Storybook features that you have enabled in your project (e.g., [decorators](../../writing-stories/decorators.mdx), [args](../../writing-stories/args.mdx)), which allows your component to render correctly. This is what is known as portable stories.

  #### Setup

  We recommend you turn off your current storyshots tests to start the migration process. To do this, rename the configuration file (i.e., `storybook.test.ts|js` or similar) to `storybook.test.ts|js.old`. This will prevent the tests from being detected, as you'll create a new testing configuration file with the same name. By doing this, you'll be able to preserve your existing tests while transitioning to portable stories before removing the Storyshots addon from your project.

  #### Import project-level annotations from Storybook

  If you need project-level annotations (e.g., [decorators](../../writing-stories/decorators.mdx), [args](../../writing-stories/args.mdx), styles) enabled in your `./storybook/preview.js|ts` included in your tests, adjust your test set up file to import the annotations as follows:

  {/* prettier-ignore-start */}

  <CodeSnippets path="portable-stories-vitest-set-project-annotations.md" />

  {/* prettier-ignore-end */}

  <Callout variant="warning">

  You **must** provide `testingLibraryRenderer` to use portable stories with Vitest or Jest.

  </Callout>

  #### Configure the testing framework for portable stories

  To help you migrate from Storyshots addon to Storybook's portable stories with the `composeStories` helper API, we've prepared examples to help you get started. Listed below are examples of two of the most popular testing frameworks: [Jest](https://jestjs.io/) and [Vitest](https://vitest.dev/). We recommend placing the code in a newly created `storybook.test.ts|js` file and adjusting the code accordingly, depending on your testing framework. Both examples below will:

  * Import all story files based on a glob pattern
  * Iterate over these files and use `composeStories` on each of their modules, resulting in a list of renderable components from each story
  * Cycle through the stories, render them, and snapshot them

  #### Vitest

  If you're using [Vitest](https://vitest.dev/) as your testing framework, you can begin migrating your snapshot tests to Storybook's portable stories with the `composeStories` helper API by referring to the following example. You will need to modify the code in your `storybook.test.ts|js` file as follows:

  {/* prettier-ignore-start */}

  <CodeSnippets path="portable-stories-vitest-snapshot-test.md" />

  {/* prettier-ignore-end */}

  When your test is executed with Vitest, it will generate a single snapshot file (i.e., `storybook.test.ts|js.snap`) with all the stories in your project. However, if you want to generate individual snapshot files, you can use Vitest's [`toMatchFileSnapshot`](https://vitest.dev/guide/snapshot.html#file-snapshots) API. For example:

  {/* prettier-ignore-start */}

  <CodeSnippets path="portable-stories-vitest-multi-snapshot-test.md" />

  {/* prettier-ignore-end */}

  #### Jest

  If you're using Jest as your testing framework, you can begin migrating your snapshot tests to Storybook's portable stories with the `composeStories` helper API by referring to the following example. You will need to modify the code in your `storybook.test.ts|js` file as follows:

  {/* prettier-ignore-start */}

  <CodeSnippets path="portable-stories-jest-snapshot-test.md" />

  {/* prettier-ignore-end */}

  When your test is executed with Jest, it will generate a single snapshot file (i.e., `__snapshots__/storybook.test.ts|js.snap`) with all the stories in your project. However, if you want to generate individual snapshot files, you can use the [`jest-specific-snapshot`](https://github.com/igor-dv/jest-specific-snapshot) package. For example:

  {/* prettier-ignore-start */}

  <CodeSnippets path="portable-stories-jest-multi-snapshot-test.md" />

  {/* prettier-ignore-end */}

  #### Known limitations

  If you opt to use portable stories in your tests, you'll have a single test file that can run in a JSDOM environment, rendering and snapshotting all your stories. However, as your project grows, you may run into the limitations you had with Storyshots previously:

  * You are not testing against a real browser.
  * You must mock many browser utilities (e.g., canvas, window APIs, etc).
  * Your debugging experience will not be as good, given you can't access the browser as part of your tests.

  Alternatively, you may want to consider migrating to the other available option for snapshot testing with Storybook: the [test-runner](#with-the-test-runner) for a more robust solution that runs tests against a real browser environment with [Playwright](https://playwright.dev/).
</IfRenderer>

***

## Troubleshooting

As running snapshot tests with Storybook and the test-runner can lead to some technical limitations that may prevent you from setting up or running your tests successfully, we've prepared a set of instructions to help you troubleshoot any issues you may encounter.

### The test-runner reports an error when running snapshot tests

If you're experiencing intermittent test failures with the test-runner, uncaught errors may occur when your tests run in the browser. These errors might not have been caught if you were using the Storyshots addons previously. The test-runner will, by default, consider these uncaught errors as failed tests. However, if these errors are expected, you can ignore them by enabling custom story tags in your stories and test-runner configuration files. For more information, please refer to the [test-runner documentation](../test-runner.mdx#experimental-filter-tests).

### The test-runner does not generate snapshot files in the expected directory

If you've configured the test-runner to run snapshot tests, you may notice that the paths and names of the snapshot files differ from those previously generated by the Storyshots addon. This is because the test-runner uses a different naming convention for snapshot files. Using a custom snapshot resolver, you can configure the test-runner to use the same naming convention you used previously.

Run the following command to generate a custom configuration file for the test-runner that you can use to configure Jest:

{/* prettier-ignore-start */}

<CodeSnippets path="test-runner-eject-config.md" />

{/* prettier-ignore-end */}

Update the file and enable the `snapshotResolver` option to use a custom snapshot resolver:

{/* prettier-ignore-start */}

<CodeSnippets path="test-runner-config-snapshot-resolver.md" />

{/* prettier-ignore-end */}

Finally, create a `snapshot-resolver.js` file to implement a custom snapshot resolver:

{/* prettier-ignore-start */}

<CodeSnippets path="test-runner-custom-snapshot-resolver.md" />

{/* prettier-ignore-end */}

### The format of the snapshot files is different from the ones generated by the Storyshots addon

By default, the test-runner uses [`jest-serializer-html`](https://github.com/algolia/jest-serializer-html) to serialize HTML snapshots. This may cause differences in formatting compared to your existing snapshots, even if you're using specific CSS-in-JS libraries like [Emotion](https://emotion.sh/docs/introduction), Angular's `ng` attributes, or other similar libraries that generate hash-based identifiers for CSS classes. However, you can configure the test-runner to use a custom snapshot serializer to solve this issue by overriding the random class names with a static one that will be the same for each test run.

Run the following command to generate a custom configuration file for the test-runner that you can use to provide additional configuration options.

{/* prettier-ignore-start */}

<CodeSnippets path="test-runner-eject-config.md" />

{/* prettier-ignore-end */}

Update the file and enable the `snapshotSerializers` option to use a custom snapshot resolver. For example:

{/* prettier-ignore-start */}

<CodeSnippets path="test-runner-config-serializer.md" />

{/* prettier-ignore-end */}

Finally, create a `snapshot-serializer.js` file to implement a custom snapshot serializer:

{/* prettier-ignore-start */}

<CodeSnippets path="test-runner-custom-snapshot-serializer.md" />

{/* prettier-ignore-end */}

When the test-runner executes your tests, it will introspect the resulting HTML and replace any dynamically generated attributes with the static ones provided by the regex expression before snapshotting the component.
